/*
	timer.cpp

	Author: Chris Haag
	Description:

		Win32 Timer functionality
*/

#include <windows.h>
#include <mmsystem.h>
#include "timer.h"

#include <stdio.h>

// Uncomment the #define if you want the program to run a fixed rate
// regardless of how much real time has passed between each frame
//#define CONST_SEC		0.035f

#define REAL_TO_SIMULATION(a) ((a) * 0.003f)

static struct			 											// Create A Structure For The Timer Information
{
  __int64       frequency;									// Timer Frequency
  float         resolution;									// Timer Resolution
  unsigned long mm_timer_start;								// Multimedia Timer Start Value
  unsigned long mm_timer_elapsed;							// Multimedia Timer Elapsed Time
  BOOL			performance_timer;							// Using The Performance Timer?
  __int64       performance_timer_start;					// Performance Timer Start Value
  __int64       performance_timer_elapsed;					// Performance Timer Elapsed Time
} timer;													// Structure Is Named timer


void Timer_Init()
{
	memset(&timer, 0, sizeof(timer));						// Clear Our Timer Structure

	// Check To See If A Performance Counter Is Available
	// If One Is Available The Timer Frequency Will Be Updated
	if (!QueryPerformanceFrequency((LARGE_INTEGER *) &timer.frequency))
	{
		// No Performace Counter Available
		timer.performance_timer	= FALSE;					// Set Performance Timer To FALSE
		timer.mm_timer_start	= timeGetTime();			// Use timeGetTime() To Get Current Time
		timer.resolution		= 1.0f/1000.0f;				// Set Our Timer Resolution To .001f
		timer.frequency			= 1000;						// Set Our Timer Frequency To 1000
		timer.mm_timer_elapsed	= timer.mm_timer_start;		// Set The Elapsed Time To The Current Time
	}
	else
	{
		// Performance Counter Is Available, Use It Instead Of The Multimedia Timer
		// Get The Current Time And Store It In performance_timer_start
		QueryPerformanceCounter((LARGE_INTEGER *) &timer.performance_timer_start);
		timer.performance_timer			= TRUE;				// Set Performance Timer To TRUE
		// Calculate The Timer Resolution Using The Timer Frequency
		timer.resolution				= (float) (((double)1.0f)/((double)timer.frequency));
		// Set The Elapsed Time To The Current Time
		timer.performance_timer_elapsed	= timer.performance_timer_start;
	}
}

float GetElapsedTime() // returns seconds
{
	__int64 time;											// time Will Hold A 64 Bit Integer

	if (timer.performance_timer)							// Are We Using The Performance Timer?
	{
		QueryPerformanceCounter((LARGE_INTEGER *) &time);	// Grab The Current Performance Time
		// Return The Current Time Minus The Start Time Multiplied By The Resolution * 1000
		return ( (float) ( time - timer.performance_timer_start) * timer.resolution) * 1000;
	}
	else
	{
		// Return The Current Time Minus The Start Time Multiplied By The Resolution * 1000
		return( (float) ( timeGetTime() - timer.mm_timer_start) * timer.resolution) * 1000;
	}
}

float GetSimulationSecondsElapsed()
{
#ifdef CONST_SEC
	return CONST_SEC;
#else
	static float t = 0;
	float fTime = GetElapsedTime();
	float fRes = fTime - t;
	t = fTime;

	return REAL_TO_SIMULATION(fRes);
#endif
}
